package com.fjzx.androidframe.network;

import android.util.SparseArray;

import com.fjzx.androidframe.network.interceptor.SsoMobileInterceptor;

import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.CookieJar;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.moshi.MoshiConverterFactory;

/**
 * {@link Retrofit} 工厂类 本项目 {@link Retrofit} 的请求是基于 {@link OkHttpClient} 此类封装了
 * {@link OkHttpClient} 的超时设置、Https证书等，用于生成 {@link Retrofit} 的网络请求实例
 *
 * @author xiongyongcong
 */
public class ApiFactory {
    /**
     * WebService 缓存
     **/
    private static SparseArray<Object> mApiCache = new SparseArray<>();
    private static final long CONNECT_TIMEOUT = 1;
    private static final long READ_TIMEOUT = 1;
    private static final long WRITE_TIMEOUT = 1;
    private static CookieJar cookieJar = CookieJar.NO_COOKIES;

    @SuppressWarnings("unchecked")
    synchronized public static <T> T getApiService(String baseUrl, Class<T> clazz) {
        T service = null;

        // 判断缓存中是否有该实例
        if (mApiCache.get(clazz.hashCode()) == null) {
            // 缓存未命中，则新建实例
            Retrofit retrofit = buildRetrofit(baseUrl);
            service = retrofit.create(clazz);
            mApiCache.put(clazz.hashCode(), service);
        } else {
            // 缓存命中，则返回实例
            service = (T) mApiCache.get(clazz.hashCode());
        }
        return service;
    }

    /**
     * 创建Retrofit实例
     *
     * @param baseUrl
     * @return
     */
    private static Retrofit buildRetrofit(String baseUrl) {
        OkHttpClient client = buildOkHttpClient();
        // Retrofit 参数配置
        return new Retrofit.Builder().baseUrl(baseUrl).client(client).addConverterFactory(MoshiConverterFactory.create()).build();
    }

    public static void setCookieJar(CookieJar cookie) {
        cookieJar = cookie;
    }

    /**
     * 创建OkHttpClient实例
     *
     * @return
     * @Param netInterceptor 拦截器
     */
    public static OkHttpClient buildOkHttpClient(Interceptor... netInterceptors) {
        return createOkHttpClientBuilder(netInterceptors).build();
    }

    public static OkHttpClient.Builder createOkHttpClientBuilder(Interceptor... netInterceptor) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.HOURS)
                .readTimeout(READ_TIMEOUT, TimeUnit.HOURS)
                .writeTimeout(WRITE_TIMEOUT, TimeUnit.HOURS);
        // 添加Cookie
        builder.cookieJar(cookieJar);
        // 添加SSO单点登录统一请求参数
        builder.addNetworkInterceptor(new SsoMobileInterceptor());

        if (netInterceptor.length > 0) {
            for (Interceptor interceptor : netInterceptor) {
                builder.addNetworkInterceptor(interceptor);
            }
        }
//        builder.proxy(Proxy.NO_PROXY);
        // Https 配置
        builder.sslSocketFactory(genSSLScoketFactory(), new TrustAllCerts());
        builder.hostnameVerifier(new MyHostnameVerifier());
        return builder;
    }

    /**
     * 创建OkHttpClient实例
     *
     * @return
     */
    public static OkHttpClient.Builder getOkHttpClientBuilder() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.hostnameVerifier(new MyHostnameVerifier());
        builder.sslSocketFactory(genSSLScoketFactory(), new TrustAllCerts());
        return builder;
    }

    private static SSLSocketFactory genSSLScoketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ssfFactory;
    }

    public static class TrustAllCerts implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    private static class MyHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
}
